package com.xinruke.hostels.reservation.user.service.impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.xinruke.hostels.cache.extract.extractor.DictInfoCacheExtractor;
import com.xinruke.hostels.cache.extract.extractor.ReservationCacheExtractor;
import com.xinruke.hostels.common.cache.ReservationUserCache;
import com.xinruke.hostels.common.constants.SysDicConstant;
import com.xinruke.hostels.common.exception.ArgumentException;
import com.xinruke.hostels.common.mybatis.MyExample;
import com.xinruke.hostels.common.po.MhHuiyuan;
import com.xinruke.hostels.common.po.MhHuiyuanQinshu;
import com.xinruke.hostels.common.util.BeanUtil;
import com.xinruke.hostels.common.util.CustomSecurity;
import com.xinruke.hostels.common.util.EmptyUtil;
import com.xinruke.hostels.common.vo.ResultVO;
import com.xinruke.hostels.common.vo.query.EConditionOperator;
import com.xinruke.hostels.common.vo.query.QueryConditions;
import com.xinruke.hostels.common.vo.query.RowsDataVO;
import com.xinruke.hostels.reservation.interfaces.api.ReservationApi;
import com.xinruke.hostels.reservation.interfaces.dto.DiscountsAddQueryDTO;
import com.xinruke.hostels.reservation.interfaces.dto.DiscountsRemainingQueryDTO;
import com.xinruke.hostels.reservation.user.interfaces.dto.*;
import com.xinruke.hostels.reservation.user.mapper.MhHuiyuanMapper;
import com.xinruke.hostels.reservation.user.mapper.MhHuiyuanQinshuMapper;
import com.xinruke.hostels.reservation.user.service.PersonalService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import tk.mybatis.mapper.entity.Example;
import tk.mybatis.mapper.util.Sqls;

import javax.annotation.Resource;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static com.xinruke.hostels.common.util.CustomSecurity.*;

/**
 * @author GuoZheng
 * @ClassName PersonalServiceImpl
 * @date：2019/6/13
 * @version: V1.0.0
 * @description：
 */
@Service
@Slf4j
public class PersonalServiceImpl implements PersonalService {

    @Resource
    private MhHuiyuanQinshuMapper mhHuiyuanQinshuMapper;
    @Resource
    private MhHuiyuanMapper mhHuiyuanMapper;
    @Resource
    private ReservationUserCache reservationUserCache;

    @Resource
    private ReservationApi reservationApi;

    @Autowired
    private DictInfoCacheExtractor dictInfoCacheExtractor;
    @Autowired
    private ReservationCacheExtractor reservationCacheExtractor;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addContacts(ContactsAddInfoDto params) {
        //身份证号加密
        params.setShenfenzhenghao(encodeIDCard(params.getShenfenzhenghao()));
        params.setShoujihao(encodeMobile(params.getShoujihao()));

        //检验是否可以插入联系人
        List<MhHuiyuanQinshu> mhHuiyuanQinshus = mhHuiyuanQinshuMapper.selectByExample(Example.builder(MhHuiyuanQinshu.class)
                .where(Sqls.custom()
                        .andEqualTo("huiyuanId", params.getHuiyuanId())
                        .andEqualTo("shanchubiaoshi", MhHuiyuanQinshu.SHANCHUBIAOSHI_BUSHANCHU)
                ).build());
        //查询身份证号和手机号是否已经存在
        List<MhHuiyuanQinshu> repetition = mhHuiyuanQinshus.stream()
                .filter(mh -> mh.getShenfenzhenghao().equals(params.getShenfenzhenghao()) || mh.getShoujihao().equals(params.getShoujihao()))
                .collect(Collectors.toList());
        if (!CollectionUtils.isEmpty(repetition)) {
            throw new ArgumentException("存在联系人信息与提交信息相同");
        }


        //根据关系分组
        Map<Byte, List<MhHuiyuanQinshu>> guanxiqinshu = mhHuiyuanQinshus.stream().collect(Collectors.groupingBy(MhHuiyuanQinshu::getGuanxi));
        if (guanxiqinshu.containsKey(params.getGuanxi())) {
            List<MhHuiyuanQinshu> count = guanxiqinshu.get(params.getGuanxi());
            if (params.getGuanxi().equals(MhHuiyuanQinshu.GUANXI_FUMU) && count.size() >= 2) {
                throw new ArgumentException("父母关系只能有两个");
            } else if (params.getGuanxi().equals(MhHuiyuanQinshu.GUANXI_PEIOUFUMU) && count.size() >= 2) {
                throw new ArgumentException("配偶父母关系只能有两个");
            } else if (params.getGuanxi().equals(MhHuiyuanQinshu.GUANXI_PEIOU) && count.size() >= 1) {
                throw new ArgumentException("只能有一个配偶");
            } else if (params.getGuanxi().equals(MhHuiyuanQinshu.GUANXI_ZIJI) && count.size() >= 1) {
                throw new ArgumentException("只能有一个自己");
            }
        }

        MhHuiyuanQinshu huiyuanQinshu = new MhHuiyuanQinshu();
        BeanUtils.copyProperties(params, huiyuanQinshu);
        huiyuanQinshu.setRenzhengzhuangtai(MhHuiyuanQinshu.RENZHENZHUANGTAI_TONGGUO);
        huiyuanQinshu.setZhuangtai(MhHuiyuanQinshu.ZHUANGTAI_YOUXIAO);
        huiyuanQinshu.setChuangjianshijian(new Date());
        huiyuanQinshu.setShanchubiaoshi(SysDicConstant.DELFLAG_0);


        mhHuiyuanQinshuMapper.insert(huiyuanQinshu);
        //直系亲属有优惠
        if (params.getGuanxi() <= MhHuiyuanQinshu.GUANXI_PEIOUFUMU) {
            DiscountsAddQueryDTO addQueryDTO = new DiscountsAddQueryDTO();
            BeanUtils.copyProperties(huiyuanQinshu, addQueryDTO);

            addQueryDTO.setQinshuguanxi(huiyuanQinshu.getGuanxi());
            addQueryDTO.setZhengjianhao(decodeIDCard(huiyuanQinshu.getShenfenzhenghao()));
            addQueryDTO.setHuiyuanId(params.getHuiyuanId());
            addQueryDTO.setQinshuId(huiyuanQinshu.getId());
            ResultVO discountApi = reservationApi.addDiscounts(addQueryDTO);
            if (discountApi.getCode() != ResultVO.SUCCESS) {
                throw new ArgumentException("初始化优惠失败");
            }
        }

    }

    @Override
    public RowsDataVO<ContactsInfo> contactsList(ContactsListQueryDTO params) {
        if (StringUtils.isEmpty(params.getUserId())) {
            params.setUserId(reservationUserCache.getCurrentUserId());
        }

        Page<MhHuiyuanQinshu> page = PageHelper.startPage(params.getPageNo(), params.getPageSize());
        List<MhHuiyuanQinshu> list = mhHuiyuanQinshuMapper.listByHuiyuanId(params.getUserId());
        if (null == list || list.size() == 0) {
            ContactsAddInfoDto contactsAddInfoDto = new ContactsAddInfoDto();
            MhHuiyuan mhHuiyuan = mhHuiyuanMapper.selectByPrimaryKey(params.getUserId());
            BeanUtil.copyProperties(mhHuiyuan, contactsAddInfoDto);
            contactsAddInfoDto.setShenfenzhenghao(CustomSecurity.decodeIDCard(mhHuiyuan.getShenfenzhenghao()));
            contactsAddInfoDto.setHuiyuanId(mhHuiyuan.getId());
            contactsAddInfoDto.setZhengjianleixing(MhHuiyuanQinshu.ZHENGJIANLEIXING_SHENFENZHENG);
            contactsAddInfoDto.setGuanxi(MhHuiyuanQinshu.GUANXI_ZIJI);
            addContacts(contactsAddInfoDto);
        }

        List<ContactsInfo> resultList = list.stream().map(n -> {
            ContactsInfo dto = new ContactsInfo();
            BeanUtils.copyProperties(n, dto);

            dto.setShengyuyouhuicishu(getDiscounts(n.getId()));
            dto.setXingbieMingCheng(dictInfoCacheExtractor.getDictValue(SysDicConstant.SEX, dto.getXingbie()));
            dto.setZhengjianleixingMingCheng(dictInfoCacheExtractor.getDictValue(SysDicConstant.ZHENGJIANLEIXING, dto.getZhengjianleixing()));
            dto.setDadanweiMingCheng(dictInfoCacheExtractor.getDictValue(SysDicConstant.DADANWEI, dto.getDadanwei()));
            dto.setZhijiedaiyuMingCheng(dictInfoCacheExtractor.getDictValue(SysDicConstant.ZHIJIDAIYU, dto.getZhijiedaiyu()));
            dto.setGuanxiMingCheng(dictInfoCacheExtractor.getDictValue(SysDicConstant.QINSHUGUANXI, dto.getGuanxi()));
            dto.setZhuangtaiMingCheng(dictInfoCacheExtractor.getDictValue(SysDicConstant.ZHUANGTAI, dto.getZhuangtai()));
            dto.setShenfenzhenghao(CustomSecurity.hideIDCard(dto.getShenfenzhenghao()));
            dto.setShoujihao(CustomSecurity.decodeMobile(dto.getShoujihao()));
            return dto;
        }).collect(Collectors.toList());

        RowsDataVO<ContactsInfo> vo = new RowsDataVO<>();
        vo.setPageNo(page.getPageNum());
        vo.setRows(resultList);
        vo.setTotalPages(page.getPages());
        vo.setTotalRecords(page.getTotal());
        return vo;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResultVO updateContacts(ContactsUpdateDto params) {
        ResultVO resultVO = ResultVO.fail();
        MhHuiyuanQinshu huiyuanQinshu = mhHuiyuanQinshuMapper.selectByPrimaryKey(params.getId());
        if (null == huiyuanQinshu) {
            resultVO.setCode(ResultVO.FAIL);
            resultVO.setMessage("该联系人不存在");
            return resultVO;
        }

        params.setShoujihao(encodeMobile(params.getShoujihao()));

        MhHuiyuanQinshu update = new MhHuiyuanQinshu();
        update.setId(params.getId());
        update.setShoujihao(params.getShoujihao());

        int count = mhHuiyuanQinshuMapper.updateByPrimaryKeySelective(update);

        if (count > 0) {
            resultVO.setCode(ResultVO.SUCCESS);
            resultVO.setMessage("操作成功");
        }
        return resultVO;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResultVO delContacts(ContactsDelDto params) {
        ResultVO resultVO = ResultVO.fail();
        MhHuiyuanQinshu huiyuanQinshu = mhHuiyuanQinshuMapper.selectByPrimaryKey(params.getId());
        if (null == huiyuanQinshu || 1 == huiyuanQinshu.getShanchubiaoshi()) {
            resultVO.setCode(ResultVO.FAIL);
            resultVO.setMessage("该联系人不存在");
            return resultVO;
        }

        Calendar cld = Calendar.getInstance();
        cld.setTime(huiyuanQinshu.getChuangjianshijian());
        cld.add(Calendar.YEAR, 1);

        if (cld.getTimeInMillis() > System.currentTimeMillis()) {
            resultVO.setMessage("当前联系人无法删除！");
            return resultVO;
        }

        MhHuiyuanQinshu update = new MhHuiyuanQinshu();
        update.setId(params.getId());
        update.setShanchubiaoshi(SysDicConstant.DELFLAG_1);

        update.setGengxinshijian(new Date());
        int count = mhHuiyuanQinshuMapper.updateByPrimaryKeySelective(update);

        if (count > 0) {
            resultVO.setCode(ResultVO.SUCCESS);
            resultVO.setMessage("操作成功");
        }
        return resultVO;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResultVO update(PersonalUpdateDto params) {
        ResultVO resultVO = ResultVO.fail();
        MhHuiyuanQinshu huiyuanQinshu = mhHuiyuanQinshuMapper.selectByPrimaryKey(params.getId());
        if (null == huiyuanQinshu) {
            resultVO.setCode(ResultVO.FAIL);
            resultVO.setMessage("该联系人不存在");
            return resultVO;
        }

        params.setShoujihao(encodeMobile(params.getShoujihao()));

        MhHuiyuanQinshu update = new MhHuiyuanQinshu();
        update.setId(params.getId());
        update.setShoujihao(params.getShoujihao());
        update.setDadanwei(params.getDadanwei());
        update.setZhijiedaiyu(params.getZhijiedaiyu());

        update.setGengxinshijian(new Date());
        int count = mhHuiyuanQinshuMapper.updateByPrimaryKeySelective(update);

        if (count > 0) {
            resultVO.setCode(ResultVO.SUCCESS);
            resultVO.setMessage("操作成功");
        }
        return resultVO;
    }

    @Override
    public ResultVO<MhHuiyuanQinshu> detail(Integer id) {
        MhHuiyuanQinshu mhHuiyuanQinshu = reservationCacheExtractor.getMhHuiyuanQinshu(id);
        if (mhHuiyuanQinshu == null) {
            return ResultVO.fail();
        }
        ResultVO<MhHuiyuanQinshu> resultVO = ResultVO.success();
        mhHuiyuanQinshu.setShenfenzhenghao(hideIDCard(mhHuiyuanQinshu.getShenfenzhenghao()));
        mhHuiyuanQinshu.setShoujihao(decodeMobile(mhHuiyuanQinshu.getShoujihao()));
        resultVO.setData(mhHuiyuanQinshu);
        return resultVO;
    }

    @Override
    public ResultVO<MhHuiyuanQinshu> getMhHuiyuanQinshu(ContactsDetailQueryDTO queryDTO) {
        ResultVO<MhHuiyuanQinshu> resultVO = ResultVO.fail();

        QueryConditions queryConditions = new QueryConditions();
        queryConditions.addCondition("id", EConditionOperator.EQULS, queryDTO.getId());
        queryConditions.addCondition("shanchubiaoshi", EConditionOperator.EQULS, SysDicConstant.DELFLAG_0);
        MyExample myExample = new MyExample(MhHuiyuanQinshu.class, queryConditions);

        List<MhHuiyuanQinshu> huiyuanQinshuList = mhHuiyuanQinshuMapper.selectByExample(myExample);
        MhHuiyuanQinshu mhHuiyuanQinshu = new MhHuiyuanQinshu();
        if (!CollectionUtils.isEmpty(huiyuanQinshuList) && huiyuanQinshuList.size() == 1) {
            mhHuiyuanQinshu = huiyuanQinshuList.get(0);
        }

        resultVO = ResultVO.success();
        resultVO.setData(mhHuiyuanQinshu);
        return resultVO;
    }

    /**
     * 详情
     *
     * @param queryDTO
     * @return
     */
    @Override
    public ResultVO<ContactsDetailResultDto> contactDetail(ContactsDetailQueryDTO queryDTO) {
        ResultVO<ContactsDetailResultDto> resultVO = ResultVO.fail();

        MhHuiyuanQinshu mhHuiyuanQinshu = new MhHuiyuanQinshu();
        if (StringUtils.isEmpty(queryDTO.getId())) {
            QueryConditions queryConditions = new QueryConditions();
            queryConditions.addCondition("shenfenzhenghao", EConditionOperator.EQULS, queryDTO.getZhengjianhao());
            queryConditions.addCondition("shanchubiaoshi", EConditionOperator.EQULS, SysDicConstant.DELFLAG_0);
            MyExample myExample = new MyExample(MhHuiyuanQinshu.class, queryConditions);

            List<MhHuiyuanQinshu> huiyuanQinshuList = mhHuiyuanQinshuMapper.selectByExample(myExample);
            if (!CollectionUtils.isEmpty(huiyuanQinshuList) && huiyuanQinshuList.size() == 1) {
                mhHuiyuanQinshu = huiyuanQinshuList.get(0);
            }
        } else {
            mhHuiyuanQinshu = reservationCacheExtractor.getMhHuiyuanQinshu(queryDTO.getId());
        }

        ContactsDetailResultDto resultDto = new ContactsDetailResultDto();
        BeanUtil.copyProperties(mhHuiyuanQinshu, resultDto);
        resultDto.setShengyuyouhuicishu(getDiscounts(mhHuiyuanQinshu.getId()));
        resultDto.setZhengjianleixingMingCheng(dictInfoCacheExtractor.getDictValue(SysDicConstant.ZHENGJIANLEIXING, resultDto.getZhengjianleixing()));
        resultDto.setXingbieMingCheng(dictInfoCacheExtractor.getDictValue(SysDicConstant.SEX, resultDto.getXingbie()));
        resultDto.setDadanweiMingCheng(dictInfoCacheExtractor.getDictValue(SysDicConstant.DADANWEI, resultDto.getDadanwei()));
        resultDto.setZhuangtaiMingCheng(dictInfoCacheExtractor.getDictValue(SysDicConstant.ZHUANGTAI, resultDto.getZhuangtai()));
        resultDto.setZhijiedaiyuMingCheng(dictInfoCacheExtractor.getDictValue(SysDicConstant.ZHIJIDAIYU, resultDto.getZhijiedaiyu()));
        resultDto.setGuanxiMingCheng(dictInfoCacheExtractor.getDictValue(SysDicConstant.QINSHUGUANXI, resultDto.getGuanxi()));
        resultDto.setShenfenzhenghao(CustomSecurity.hideIDCard(resultDto.getShenfenzhenghao()));
        resultDto.setShoujihao(CustomSecurity.decodeMobile(resultDto.getShoujihao()));

        resultVO = ResultVO.success();
        resultVO.setData(resultDto);
        return resultVO;
    }

    private Integer getDiscounts(Integer contactId) {
        DiscountsRemainingQueryDTO discountsRemainingQueryDTO = new DiscountsRemainingQueryDTO();
        discountsRemainingQueryDTO.setContactIds(contactId);
        discountsRemainingQueryDTO.setRuzhushijian(new Date());
        ResultVO<Integer> remaining = reservationApi.remaining(discountsRemainingQueryDTO);
        return remaining.getData();
    }

    @Override
    public ResultVO<BlacklistQueryResultDTO> isBlacklist(BlacklistQueryDTO blacklistQueryDTO) {
        ResultVO<BlacklistQueryResultDTO> resultVO = ResultVO.success();

        blacklistQueryDTO.setZhengjianhao(encodeIDCard(blacklistQueryDTO.getZhengjianhao()));

        QueryConditions andConditions = new QueryConditions();
        andConditions.addCondition("shenfenzhenghao", EConditionOperator.EQULS, blacklistQueryDTO.getZhengjianhao());
        andConditions.addCondition("zhengjianleixing", EConditionOperator.EQULS, blacklistQueryDTO.getZhengjianleixing());
        andConditions.addCondition("shanchubiaoshi", EConditionOperator.EQULS, SysDicConstant.DELFLAG_0);
        MyExample myExample = new MyExample(MhHuiyuanQinshu.class, andConditions);
        List<MhHuiyuanQinshu> mhHuiyuanQinshus = mhHuiyuanQinshuMapper.selectByExample(myExample);
        if (EmptyUtil.isEmpty(mhHuiyuanQinshus)) {
            return resultVO;
        }
        BlacklistQueryResultDTO blacklistQueryResultDTO = new BlacklistQueryResultDTO();
        if (MhHuiyuanQinshu.ZHUANGTAI_WUXIAO.equals(mhHuiyuanQinshus.get(0).getZhuangtai())) {
            blacklistQueryResultDTO.setIsBlacklist(true);
            resultVO.setData(blacklistQueryResultDTO);
            return resultVO;
        }
        blacklistQueryResultDTO.setIsBlacklist(false);
        resultVO.setData(blacklistQueryResultDTO);
        return resultVO;
    }
}
